package com.wiscamp.ninechapters.panels.domain.entities;

import com.wiscamp.ninechapters.panels.domain.enums.AccountTypes;
import com.wiscamp.ninechapters.panels.domain.enums.UserTypes;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import cube.ddd.domain.Entity;
import lombok.Data;
import lombok.experimental.Accessors;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;

/**
 * 用户表
 */
@Data
@Accessors(chain = true)
public class User implements Entity {

    /**
     * 用户编号
     */
    private long userId = 0L;

    /**
     * 应用编号
     */
    private long applicationId = 0L;

    /**
     * 用户代码
     */
    private String userCode = "";

    /**
     * 用户姓名
     */
    private String userName = "";

    /**
     * 用户类型编号
     */
    private long userTypeId = 0L;

    /**
     * 账号类型编号
     */
    private long accountTypeId = 0L;

    /**
     * 加密口令
     */
    private String password = "";

    /**
     * 关联账户编号
     */
    private long referenceId = 0L;

    /**
     * 关联账户代码
     */
    private String referenceCode = "";

    /**
     * 组织机构编号
     */
    private long organizationId = 0L;

    /**
     * 成员编号
     */
    private long personId = 0L;

    /**
     * 邮箱
     */
    private String email = "";

    /**
     * 手机号码
     */
    private String cellphone = "";

    /**
     * 备注
     */
    private String remark = "";

    /**
     * 创建用户
     */
    private long creatorId = 0L;

    /**
     * 创建时间
     */
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    private LocalDateTime creationTime;

    /**
     * 编辑用户
     */
    private long modifierId = 0L;

    /**
     * 编辑时间
     */
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    private LocalDateTime modificationTime;

    /**
     * 是否启用
     */
    private boolean enabled = true;

    /**
     * 是否删除
     */
    private boolean deleted = false;

    /**
     * 用户组类型名称
     */
    private String userTypeName = "";

    /**
     * 用户组类型名称
     */
    private String accountTypeName = "";

    /**
     * 创建人名称
     */
    private String creatorName = "";

    /**
     * 编辑人名称
     */
    private String modifierName = "";

    public void enable() {
        if (!this.enabled) {
            this.enabled = true;
        }
    }

    public void disable() {
        if (this.enabled) {
            this.enabled = false;
        }
    }

    public void delete() {
        if (!this.deleted) {
            this.deleted = true;
        }
    }

    public void createBy(long operatorId) {
        this.creatorId = operatorId;
        this.creationTime = LocalDateTime.now();
        this.modifierId = operatorId;
        this.modificationTime = LocalDateTime.now();
    }

    public void updateBy(long operatorId) {
        this.modifierId = operatorId;
        this.modificationTime = LocalDateTime.now();
    }

    //region roleMenus
    private Collection<Long> menuIds = new ArrayList<>();
    //endregion

    //region rolePermissions
    private Collection<Long> permissionIds = new ArrayList<>();
    //endregion

    private Collection<Long> roleIds = new ArrayList<>();

    private Collection<Long> roleIdsInUser = new ArrayList<>();

    private Collection<Long> roleIdsInGroups = new ArrayList<>();

    private Collection<Long> groupIds = new ArrayList<>();

    public User() {
        //
    }

    public User(long appId, String userCode, String userName, UserTypes userType, AccountTypes accountType) {
        this.setApplicationId(appId);
        this.setUserCode(userCode);
        this.setUserName(userName);
        if (Objects.nonNull(userType)) {
            this.setUserTypeId(userType.getIndex());
        }
        if (Objects.nonNull(accountType)) {
            this.setAccountTypeId(accountType.getIndex());
        }
    }

    public void changePassword(String password) {
        this.setPassword(password);
    }

    public void relateToPerson(long organizationId, long personId) {
        this.setOrganizationId(organizationId);
        this.setPersonId(personId);
    }

    public void changeContactInfo(String email, String cellphone) {
        if (email != null || !email.isEmpty())
            this.setEmail(email);

        if (cellphone != null || !cellphone.isEmpty())
            this.setCellphone(cellphone);
    }

    public static User of(long appId, String userCode, String userName, UserTypes userType, AccountTypes accountType) {
        return new User()
                .setApplicationId(appId)
                .setUserCode(userCode)
                .setUserName(userName)
                .setUserTypeId(userType.getIndex())
                .setAccountTypeId(accountType.getIndex());
    }
}
